#include <iostream>

using namespace std;
//普通函数与函数模板的调用规则
//调用规则如下：
//1. 如果函数模板和普通函数都可以实现，优先调用普通函数
//2. 可以通过空模板参数列表来强制调用函数模板
//3. 函数模板也可以发生重载
//4. 如果函数模板可以产生更好的匹配,优先调用函数模板


void myPrint(int a, int b) {
    cout << "调用的普通函数myPrint(int,int)" << endl;
}

template<typename T>
void myPrint(T a, T b) {
    cout << "调用的函数模板myPrint(T,T)" << endl;
}

template<typename T>
void myPrint(T a, T b, T c) {
    cout << "调用的函数模板myPrint(T,T,T)" << endl;
}

void test() {
    int a = 10;
    int b = 20;
    //1、如果函数模板和普通函数都可以实现，优先调用普通函数
    //注意 如果告诉编译器  普通函数是有的，但只是声明没有实现，或者不在当前文件内实现，就会报错找不到
    myPrint(a, b);
    //2、可以通过空模板参数列表来强制调用函数模板
    myPrint<>(a, b); //调用函数模板
    //3、函数模板也可以发生重载
    int c = 30;
    myPrint(a, b, c); //调用重载的函数模板
    //4、 如果函数模板可以产生更好的匹配,优先调用函数模板
    char c1 = 'a';
    char c2 = 'b';
    myPrint(c1, c2); //调用函数模板
}

//既然提供了函数模板，最好就不要提供普通函数，否则容易出现二义性
int main() {
    test();
    return 0;
}